package com.jacky.demo.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.inputmethod.EditorInfo;

import com.jacky.demo.R;
import com.jacky.demo.util.AppUtils;

import java.util.Arrays;

import static android.graphics.Paint.ANTI_ALIAS_FLAG;

/**
 * 仿支付宝的数字密码输入框
 */
public class NumberPasswordEditText extends AppCompatEditText implements TextWatcher {

    public NumberPasswordEditText(Context context) {
        super(context);
        initView(context, null);
    }

    public NumberPasswordEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context, attrs);
    }

    public NumberPasswordEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    private int borderColor;
    private float borderWidth;
    private float borderRadius;

    private int textLength;
    private int maxLength;

    private Paint passwordPaint;
    private Paint borderPaint = new Paint(ANTI_ALIAS_FLAG);

    private final int defaultContMargin = 1;// 外面外框线的宽度
    private final int defaultSplitLineWidth = 1;// 里面线的宽度
    private int textWidth, textHeight;
    private Rect bound = new Rect();
    private char[] mChars;

    private void initView(Context context, AttributeSet attrs) {
        setInputType(InputType.TYPE_CLASS_NUMBER);
        setImeOptions(EditorInfo.IME_ACTION_GO);
        //禁止复制黏贴
        setLongClickable(false);
        setTextIsSelectable(false);
        setCustomSelectionActionModeCallback(new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {return false;}
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {return false;}
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {return false;}
            @Override
            public void onDestroyActionMode(ActionMode mode) {}
        });
        setSingleLine();

        final int defaultBorderColor = 0xffCACBCC;
        final float defaultBorderWidth = AppUtils.dp2px(context, 1);
        final float defaultBorderRadius = defaultBorderWidth;
        final int defaultPasswordLength = 6;

        addTextChangedListener(this);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumberPasswordEditText);
        borderColor = a.getColor(R.styleable.NumberPasswordEditText_borderColor,defaultBorderColor);
        borderWidth = a.getDimension(R.styleable.NumberPasswordEditText_borderWidth,defaultBorderWidth);
        borderRadius = a.getDimension(R.styleable.NumberPasswordEditText_borderRadius,defaultBorderRadius);
        maxLength = a.getInt(R.styleable.NumberPasswordEditText_android_maxLength,defaultPasswordLength);
        int textType = a.getInt(R.styleable.NumberPasswordEditText_textChar, 0);
        a.recycle();

        setFilters(new InputFilter[]{ new InputFilter.LengthFilter(maxLength)});
        borderPaint.setStrokeWidth(borderWidth);
        borderPaint.setColor(borderColor);

        if(textType == 1 || textType == 2) {
            mChars = new char[maxLength];
            Arrays.fill(mChars, textType == 1 ? '*' : '●');
        }
        passwordPaint = getPaint();
        textLength = getText().length();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();

        // 外边框
        RectF rect = new RectF(0, 0, width, height);
        borderPaint.setColor(borderColor);
        canvas.drawRoundRect(rect, borderRadius, borderRadius, borderPaint);

        // 内容区
        RectF rectIn = new RectF(
                rect.left + defaultContMargin,
                rect.top + defaultContMargin,
                rect.right - defaultContMargin,
                rect.bottom-1);
        borderPaint.setColor(Color.WHITE);
        canvas.drawRoundRect(rectIn, borderRadius, borderRadius, borderPaint);

        // 分割线
        borderPaint.setColor(borderColor);
        borderPaint.setStrokeWidth(defaultSplitLineWidth);
        for (int i = 1; i < maxLength; i++) {
            float x = width * i / maxLength;
            canvas.drawLine(x, 0, x, height, borderPaint);
        }

        // 密码
        float cx, cy = height / 2, offset = 0;
        float half = width / maxLength / 2;
        if(mChars == null) {
            //绘制原文
            String sequence = getText().toString();
            for (int i = 0; i < textLength; i++) {
                cx = width * i / maxLength + half;

                passwordPaint.getTextBounds(sequence,i, i + 1, bound);
                textWidth = bound.width() / 2;
                textHeight = bound.height()/2;
                canvas.drawText(sequence, i, i + 1, cx - textWidth, cy + textHeight, passwordPaint);
            }
        } else {
            //绘制替换符
            passwordPaint.getTextBounds(mChars,0, 1, bound);
            textWidth = bound.width() / 2;
            textHeight = bound.height()/2;
            if(mChars[0] == '*') {
                //因为星号字符的内容靠上显示，所以绘制的时候需要加些偏移量，界面上看起来才像是居中
                offset = textHeight * 1.5f;
            }
            for (int i = 0; i < textLength; i++) {
                cx = width * i / maxLength + half;
                canvas.drawText(mChars, i, 1,
                        cx - textWidth, cy + textHeight + offset, passwordPaint);
            }
        }
    }

    @Override
    public final void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public final void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public final void afterTextChanged(Editable s) {
        textLength = s.length();
        invalidate();
    }

    public int getMaxLength() {
        return maxLength;
    }
}
